package dataService;


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import logic.Config;
import logic.vhomeAPI;

import org.apache.amber.oauth2.as.issuer.MD5Generator;
import org.apache.amber.oauth2.as.issuer.OAuthIssuer;
import org.apache.amber.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.amber.oauth2.as.request.OAuthAuthzRequest;
import org.apache.amber.oauth2.as.request.OAuthTokenRequest;
import org.apache.amber.oauth2.as.response.OAuthASResponse;
import org.apache.amber.oauth2.common.OAuth;
import org.apache.amber.oauth2.common.error.OAuthError;
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.exception.OAuthSystemException;
import org.apache.amber.oauth2.common.message.OAuthResponse;
import org.apache.amber.oauth2.common.message.types.GrantType;
import org.apache.amber.oauth2.common.message.types.ParameterStyle;
import org.apache.amber.oauth2.common.utils.OAuthUtils;
import org.apache.amber.oauth2.ext.dynamicreg.server.request.OAuthServerRegistrationRequest;
import org.apache.amber.oauth2.ext.dynamicreg.server.response.OAuthServerRegistrationResponse;
import org.apache.amber.oauth2.rs.request.OAuthAccessResourceRequest;
import org.apache.amber.oauth2.rs.response.OAuthRSResponse;
import org.apache.log4j.Logger;
import org.jooq.SQLDialect;

import datatypes.vhomeAccess;
import datatypes.vhomeClass;
import datatypes.vhomeClient;
import datatypes.vhomeObject;
import datatypes.vhomeTimeSeriesElement;
@Path("/")
public class ServiceClass {
	
	/*@Context
	UriInfo uriInfo;
	@Context
	Request request;
	*/
	@Context
	HttpServletRequest inRequest;
	@Context
	Request inReq;
	private static Logger log = Logger.getLogger(ServiceClass.class.getName());
	/*GET STREAMTYPE METHODS*/
	@Path("/ListAllStreamTypes")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response listAllStreamTypes(@Context
			HttpServletRequest inRequest) throws OAuthSystemException, SecurityException, IOException
	{
		
		log.info("API accessed: ListAllStreamTypes");
		//String variable = System.getProperty("catalina.home");  
		//System.out.println(variable); 
		/*log.info("helo");
		log.trace("trace");

		log.info("debug");

		log.info("Info");

		log.warn("Warn");

		log.error("Error");

		log.fatal("Fatal");*/
		
		Response r = resource(inRequest,"ListAllStreamTypes");
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
			
		
		HashMap<String,String> m1 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeClass> retVals = new ArrayList<vhomeClass>(); 
		retVals = api.getClass(m1);
		api.close();
		
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Response.Status.OK).entity(retVals).build();
	}
	@Path("/ListStreamType/stid/{stid}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response listStreamTypeByStid(@PathParam("stid") int stid)
	{
		log.info("API accessed: ListStreamTypeByStid");
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("cid", stid+"");
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeClass> retVals = new ArrayList<vhomeClass>(); 
		retVals = api.getClass(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}
	@Path("/ListStreamType/stname/{stname}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response listStreamTypeBySname(@PathParam("stname") String stname)
	{
		log.info("API accessed: ListStreamTypeByStname");
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("cname", stname);
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeClass> retVals = new ArrayList<vhomeClass>(); 
		retVals = api.getClass(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}
	@Path("/ListStreamType/rating/{rating_low}/{rating_high}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response listStreamTypeByRating(@PathParam("rating_low") float rating_low,@PathParam("rating_high") float rating_high )
	{
		log.info("API accessed: ListStreamTypeByRating");
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("rating_low", ""+rating_low);
		m1.put("rating_high", ""+rating_high);
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeClass> retVals = new ArrayList<vhomeClass>(); 
		retVals = api.getClass(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}

	
	/*GET DATASTREAM METHODS*/
	@Path("/ListAllDataStreams")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listAllDataStreams() {
		log.info("API accessed: ListAllDataStreams");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>(); 
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/stid/{stid}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsByStid(@PathParam("stid") int stid) {
		log.info("API accessed: ListDataStreamByStid");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("cid", stid+""); 
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/stname/{stname}/")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsByStname(@PathParam("stname") String sname) {
		log.info("API accessed: ListDataStreamByStname");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("cname", sname+""); 
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/rating/{rating_low}/{rating_high}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsByRating(@PathParam("rating_low") int r1, @PathParam("rating_high") int r2) {
		log.info("API accessed: ListDataStreamByRating");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("rating_low", r1+""); 
		m1.put("rating_high", r2+"");
		
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/granularity/{granularity_low}/{granularity_high}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsByGranularity(@PathParam("granularity_low") int g1, @PathParam("granularity_high") int g2) {
		log.info("API accessed: ListDataStreamByGranularity");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		
		m2.put("granularity_low", ""+g1);
		m2.put("granularity_high", ""+g2);
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
		
	@Path("/ListDataStream/stid/{stid}/dsid/{dsid}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsById(@PathParam("stid") int stid,@PathParam("dsid") int dsid) {
		log.info("API accessed: ListDataStreamById");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("cid", stid+""); m2.put("oid", ""+dsid);
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/stname/{stname}/dsname/{dsname}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	
public Response listDataStreamsByName(@PathParam("stname") String stname, @PathParam("dsname") String dsname) {
		
		log.info("API accessed: ListDataStreamByName");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("cname", stname+""); m2.put("oname", ""+dsname);

		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	@Path("/ListDataStream/rating/{rating_low}/{rating_high}/granularity/{granularity_low}/{granularity_high}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })		
	public Response listDataStreamsByRatingGranularity(@PathParam("rating_low") int r1, @PathParam("rating_high") int r2,
			@PathParam("granularity_low") int g1, @PathParam("granularity_high") int g2) {
		
		log.info("API accessed: ListDataStreamByRatingGranularity");
		HashMap<String,String> m1 = new HashMap<String,String>();
		HashMap<String,String> m2 = new HashMap<String,String>();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeObject> retVals = new ArrayList<vhomeObject>();
		m1.put("rating_low", r1+""); 
		m1.put("rating_high", r2+"");
		
		m2.put("granularity_low", ""+g1);
		m2.put("granularity_high", ""+g2);
		retVals = api.getObject(m1,m2);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
			
	}
	
	
	/* GET TIMESERIES METHODS*/
	@Path("/GetTimeSeries/stid/{stid}/dsid/{dsid}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response getTimeSeries(@PathParam("stid") int stid, @PathParam("dsid") int dsid) throws OAuthSystemException
	{
		log.info("API accessed: getTimeSeries");
		Response r = resource(inRequest,"GetTimeSeries/stid/"+stid+"/dsid/"+dsid);
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
		
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("cid", stid+"");m1.put("oid", dsid+"");
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeTimeSeriesElement> retVals = new ArrayList<vhomeTimeSeriesElement>(); 
		retVals = api.getSeries(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}
	@Path("/GetTimeSeries/stid/{stid}/dsid/{dsid}/timestamp/{timestamp_start}/{timestamp_end}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response getTimeSeriesByTimestamp(@PathParam("stid") int stid, @PathParam("dsid") int dsid, 
			@PathParam("timestamp_start") long ts1, @PathParam("timestamp_end") long ts2) throws OAuthSystemException
	{
		log.info("API accessed: getTimeSeries");
		Response r = resource(inRequest,"GetTimeSeries/stid/"+stid+"/dsid/"+dsid +"/timestamp/"+ts1+"/"+ts2);
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
		
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("cid", stid+"");m1.put("oid", dsid+"");
		m1.put("timestamp_low", ts1+"");m1.put("timestamp_high", ts2+"");
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeTimeSeriesElement> retVals = new ArrayList<vhomeTimeSeriesElement>(); 
		retVals = api.getSeries(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}
	@Path("/GetTimeSeries/stid/{stid}/dsid/{dsid}/value/{value_min}/{value_max}")	
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Response getTimeSeriesByTimestamp(@PathParam("stid") int stid, @PathParam("dsid") int dsid, 
			@PathParam("value_min") double v1, @PathParam("value_max") double v2) throws OAuthSystemException
	{
		
		log.info("API accessed: getTimeSeriesByTimestamp");
		Response r = resource(inRequest,"GetTimeSeries/stid/"+stid+"/dsid/"+dsid +"/value/"+v1+"/"+v2);
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
		
		HashMap<String,String> m1 = new HashMap<String,String>();
		m1.put("cid", stid+"");m1.put("oid", dsid+"");
		m1.put("value_low", v1+"");m1.put("value_high", v2+"");
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		List<vhomeTimeSeriesElement> retVals = new ArrayList<vhomeTimeSeriesElement>(); 
		retVals = api.getSeries(m1);
		api.close();
		log.info("Response: OK, retVals: "+retVals);
		return Response.status(Status.OK).entity(retVals).build();
	}
	
	
	/*Add STREAMTYPE, DATASTREAM and TIMESERIES METHODS*/
	@Path("/AddStreamType")	
	@POST
	@Produces({ MediaType.APPLICATION_JSON })
	public Response addStreamType( MultivaluedMap<String, String> form) throws OAuthSystemException  
	{
		log.info("API accessed: AddStreamType");
		Response r = resource(inRequest,"AddStreamType");
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
		
		int stid;
		try 
		{
			if(form.getFirst("stname")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: stname");}
			if(form.getFirst("descriptor")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: descriptor");}
			if(form.getFirst("rating")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: rating");}
			try 
			{
				Float.parseFloat(form.getFirst("rating"));
			}
			catch(Exception e)
			{
				throw OAuthProblemException.error("invalid_request").description("Invalid parameter value: rating");
			}
			
		String stname = form.getFirst("stname").toString();
		String descriptor = form.getFirst("descriptor").toString();
		String rating = form.getFirst("rating").toString();
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) {throw OAuthProblemException.error("server_error").description("Server database error");}
		HashMap<String,String> m = new HashMap<String,String>();
		m.put("descriptor", descriptor);
		m.put("cname",stname);
		m.put("rating",rating);
		stid = api.addClass(m);
		if(stid==0) {throw OAuthProblemException.error("server_error").description("Server database error");}
		api.close();
		
		if(api.init()!=1) {throw OAuthProblemException.error("server_error").description("Server database error");}
		List<vhomeClass> v = new ArrayList<vhomeClass>();
		m.clear();
		m.put("cid", ""+stid);
		v = api.getClass(m);
		log.info("Response: OK, return: "+v);
		return Response.status(Response.Status.OK).entity(v).build();
		
		}
		catch (OAuthProblemException e) {
	        	e.printStackTrace();
	            OAuthResponse response = OAuthServerRegistrationResponse
	                .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
	                .error(e)
	                .buildJSONMessage();
	            log.warn(e.getError()+","+e.getDescription() + ","+e.getStackTrace());
	            log.info("Response: BAD_REQUEST");
	            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
	     }
		
		
	}
	@Path("/AddDataStream")	
	@POST
	@Produces({ MediaType.APPLICATION_JSON })
	public Response addDataStream( MultivaluedMap<String, String> form) throws OAuthSystemException  
	{
		log.info("API accessed: AddDataStream");
		Response r = resource(inRequest,"AddDataStream");
		if(Response.Status.OK.getStatusCode()!=r.getStatus()) return r;
		
		int dsid;
		try 
		{
			if(form.getFirst("dsname")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: dsname");}
			if(form.getFirst("stid")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: stid");}
			//if(form.getFirst("symbol")!=null && form.getFirst("symbol").toString().length()>1) {throw OAuthProblemException.error("invalid_request").description("Invalid parameter value: symbol");}
			//if(form.getFirst("descriptor")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: descriptor");}
			//if(form.getFirst("granularity")==null) {throw OAuthProblemException.error("invalid_request").description("Missing parameter: granularity");}
			try 
			{
				Integer.parseInt(form.getFirst("stid"));
				if(form.getFirst("granularity")!=null) Integer.parseInt(form.getFirst("granularity"));
			}
			catch(Exception e)
			{
				throw OAuthProblemException.error("invalid_request").description("Invalid parameter value: stid or granularity");
			}
			
		String dsname = form.getFirst("dsname")==null ?  null : form.getFirst("dsname").toString();
		String descriptor = form.getFirst("descriptor")==null ? null : form.getFirst("descriptor").toString();
		String granularity =  form.getFirst("granularity")==null ? null : form.getFirst("granularity").toString();
		String stid = form.getFirst("stid") ==null? null : form.getFirst("stid").toString();
		String symbol = form.getFirst("symbol")==null ? ""  : form.getFirst("symbol").toString();
		
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) {throw OAuthProblemException.error("server_error").description("Server database error");}
		
		HashMap<String,String> m = new HashMap<String,String>();
		if(descriptor!=null)
			m.put("descriptor", descriptor);
		if(dsname!=null)
			m.put("oname",dsname);
		if(granularity!=null)
			m.put("granularity",granularity);
		if(stid!=null)
			m.put("cid",stid);
		if(symbol!=null)
			m.put("symbol",symbol+"");
		
		dsid = api.addObject(m);
		if(dsid==0) {throw OAuthProblemException.error("invalid_request").description("Invalid parameter: stid");}
		api.close();
		
		if(api.init()!=1) {throw OAuthProblemException.error("server_error").description("Server database error");}
		List<vhomeObject> v = new ArrayList<vhomeObject>();
		m.clear();
		m.put("cid", ""+stid);
		HashMap<String,String> n = new HashMap<String,String>();
		n.put("oid", ""+dsid);
		v = api.getObject(m,n);
		log.info("Response: OK, return: "+v);
		return Response.status(Response.Status.OK).entity(v).build();
		
		}
		catch (OAuthProblemException e) {
	        	e.printStackTrace();
	            OAuthResponse response = OAuthServerRegistrationResponse
	                .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
	                .error(e)
	                .buildJSONMessage();
	            log.warn(e.getError()+","+e.getDescription()+","+e.getStackTrace());
	            log.info("Response: BAD_REQUEST");
	          
	            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
	     }
		
		
	}
	@Path("/AddTimeSeries/stid/{stid}/dsid/{dsid}")
	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Response addSeries(List<vhomeTimeSeriesElement> s, @PathParam("stid") int stid , @PathParam("dsid") int dsid )
	{
		log.info("API accessed: AddSeries");
		vhomeAPI api = new vhomeAPI();
		if(api.init()!=1) 
		{
			return Response.status(Response.Status.OK).entity("{\"error\":server_error,\"description:\"server database error}").build();
		}
		Iterator i = s.iterator();
		HashMap<String,Integer> m = new HashMap<String,Integer>();
		m.put("cid", stid);
		m.put("oid", dsid);
		Long[] ts = new Long[s.size()];
		Double[] val = new Double[s.size()];
		int j=0;
		while(i.hasNext() && s.size() >=1)
		{
			vhomeTimeSeriesElement e = (vhomeTimeSeriesElement) i.next() ; 
			ts[j] = e.getTimestamp();
			val[j] = e.getValue();
			j++;
			System.out.println(e.getTimestamp() + ":" +  e.getValue());
			
		}
		log.info("Response: OK");
		return Response.status(Status.OK).entity(api.addSeries(ts,val, m)).build();
		
		
		
	}
	
	/* OAUTH METHODS*/
	@Path("/accept")
	@RolesAllowed("manager")
	@GET
	@Produces( MediaType.TEXT_HTML )
	public Response accept(@Context HttpServletRequest inRequest )
	{
		
		log.info("API accessed: accept");
		String grant = inRequest.getParameter("grant"); 
		HttpSession session = inRequest.getSession(true);
	    //session.setAttribute("MySessionVariable", 1);
	    Integer param = (Integer) session.getAttribute("Authentication");
	    String redirectURI = (String)session.getAttribute("redirectURI");
	    String clientid = (String)session.getAttribute("clientId");
	    String scope = (String)session.getAttribute("scope");
	    
	    if(param==null)
	    {
	    session.invalidate(); 
	    log.warn("Invalid Request: Session not authenticated");
	    return Response.status(200).entity("<html>Invalid Request</html>").build();
	    }
	    else if(grant.equals("accept"))
	    {	
	        OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
	        OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.
	        authorizationResponse(inRequest,HttpServletResponse.SC_FOUND);
	        try {
	        	String code = oauthIssuerImpl.authorizationCode(); 
	        builder.setCode(code);
	        builder.setExpiresIn(""+Config.CodeLifespan);
	        final OAuthResponse response = builder.location(redirectURI).buildQueryMessage();	        
	        URI url = new URI(response.getLocationUri());
	        
	        vhomeAPI api = new vhomeAPI();
	        if(api.init()==1)
	        {
	           HashMap<String,String> m = new HashMap<String,String>();
	  		   m.put("clientid", clientid);
	  		   m.put("code",code );
	  		   m.put("scope", scope);
	  		   m.put("expiresCode", Config.CodeLifespan+"");
	  		   m.put("expiresToken", Config.TokenLifespan+"");
	  		   api.addAccess(m);
	  		   api.close();
	        }
	        
	        
	        
	        session.invalidate(); 
	        log.info("Response: OK request accepted redirect: "+url);
	        return Response.status(response.getResponseStatus()).location(url).build();
	        }
	        catch(Exception e)
	        {
	        	log.warn("Exception : Request Error, "+ e.getStackTrace());
	        	e.printStackTrace();
	        	return Response.status(200).entity("<html>Error</html>").build();
	        }
	        
	    }
	    else
	    {
	      	session.invalidate(); 
	       	OAuthProblemException e = OAuthProblemException.error("request_denied");
        	e.setRedirectUri(redirectURI);
        	e.description("Access request denied");
        	 log.warn(e.getError()+","+e.getDescription()+","+e.getStackTrace());
	          
	          
	    	final Response.ResponseBuilder responseBuilder = Response.status(HttpServletResponse.SC_FOUND);
	        OAuthResponse response;
			try {
				response = OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
				        .error(e)
				        .location(redirectURI).buildQueryMessage();
				  final URI location = new URI(response.getLocationUri());
				  log.info("Response: OK request rejected redirect: "+location);        
		          return responseBuilder.location(location).build();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				log.warn("Exception : Request Error, "+ e1.getStackTrace());
				return Response.status(200).entity("<html>Request denied</html>").build();
			}
	    	
	    	
	    }
			
	}
	@Path("/authorize")
	@RolesAllowed("manager")
	@GET
	public Response authorize(@Context HttpServletRequest inRequest)
    throws URISyntaxException, OAuthSystemException {
    OAuthAuthzRequest oauthRequest;
    HttpSession session = inRequest.getSession(true);
    //OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
    try {
    	log.info("API accessed: authorize");
    	
    	session.setAttribute("Authentication", 1);
    	//Integer param = (Integer) session.getAttribute("MySessionVariable");
    	
        oauthRequest = new OAuthAuthzRequest(inRequest);
        
        if(oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI)==null) { 
        	Response.ResponseBuilder responseBuilder = Response.status(HttpServletResponse.SC_FOUND);
        	return 	responseBuilder.entity("OAuth callback url needs to be provided by client!!!").build();
    	}
        
        //build response according to response_type
        String redirectURI = new String(inRequest.getParameter(OAuth.OAUTH_REDIRECT_URI));
        session.setAttribute("redirectURI", redirectURI);
        String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
        session.setAttribute("responseType", responseType);
        String clientId = oauthRequest.getParam(OAuth.OAUTH_CLIENT_ID);
        session.setAttribute("clientId", clientId);
        String scope = oauthRequest.getParam(OAuth.OAUTH_SCOPE);
        session.setAttribute("scope", scope);
        
        if(scope==null) {
        	OAuthProblemException e = OAuthProblemException.error("invalid_request");
        	e.setRedirectUri(redirectURI);
        	e.description("Missing scope parameter value");
        	throw e;
        }
        
        // DONE : Add missing / null check values.
        // TODO: lookup client ID in db
        
        //OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse.
        //authorizationResponse(request,HttpServletResponse.SC_FOUND);
         
        //extract reqd parameter values out of the request
        //build response according to response_type
        String HTMLresponse = new String();
        String path = inRequest.getContextPath();
        vhomeAPI api = new vhomeAPI();
        String regDetails ="";
        if(api.init()==1)
        {
           HashMap<String,String> m = new HashMap<String,String>();
  		   m.put("clientid", clientId);
  		   List<vhomeClient> c = new ArrayList<vhomeClient>(); 
  		   c = api.getClient(m);api.close();
  		   
  		   if(c.size()==0)
  		   {
  	        	OAuthProblemException e = OAuthProblemException.error("invalid_request");
  	        	e.setRedirectUri(redirectURI);
  	        	e.description("Client not registered");
  	        	throw e;
  			   
  		   }
  		   
  		   int i;
  		   for(i=0; i < 1 ; i++)
  		   {regDetails+= "<br/> <br/>Registration : <br/>Name: "+ c.get(i).getName() + " <br/>URL: "+ c.get(i).getUrl() 
  		   				+ " <br/>Description: " + c.get(i).getDescription() + " <br/>Redirect URI: " + c.get(i).getRedirecturi()
  		   				+ " <br/>ID: "+c.get(i).getClientid() + " <br/>Issued: "+c.get(i).getIssuedat()+ "<br/>";
  		   }
  		   
  		   if(!c.get(0).getRedirecturi().equals(redirectURI))
  		   {
  			 	OAuthProblemException e = OAuthProblemException.error("redirect_uri_mismatch");
  	        	e.setRedirectUri(redirectURI);
  	        	e.description("Redirect URI does not match registered "+ c.get(0).getRedirecturi());
  	        	throw e;
  		   }
  		   
  		   
        }
        
        HTMLresponse = "<html> " 
				+ "<title>" + "Authorization Request" + "</title>"
				+ "<body><h1>"
				+ "Application requesting access</h1><h2> <br/>"
				+ "Client ID: "+ clientId  
				+ "<br/> Request Redirect URI: " + redirectURI
				+ "<br/>Requested Scope: " + scope 
				+ "<br/>Response Type:" + responseType
				+ regDetails
				+ "</h2> <h3> <form method='get' action='"+path+"/accept' >" +
				"<input name='grant' type=\"submit\" value=\"accept\"  />  " +
				"<input name='grant' type=\"submit\" value=\"reject\" /> </form> " +
				"</h3></body></html> ";
     
       return Response.status(200).entity(HTMLresponse).build();
      

    } 
    
    catch (OAuthProblemException e) {

    	session.invalidate();
        final Response.ResponseBuilder responseBuilder = Response.status(HttpServletResponse.SC_FOUND);
        e.printStackTrace();
        String redirectUri = e.getRedirectUri();
        //String scope = e.getScope();
        System.out.println(e.getError());
        log.warn(e.getError()+","+e.getDescription()+","+e.getStackTrace());
       
      
        
        if (OAuthUtils.isEmpty(redirectUri)) {
        	 log.info("Invalid Request missing redirect URI");
        	throw new WebApplicationException(
                responseBuilder.entity("OAuth callback url needs to be provided by client!!!").build());
        }
        
        
        final OAuthResponse response = OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
            .error(e)
            .location(redirectUri).buildQueryMessage();
        final URI location = new URI(response.getLocationUri());
        
         return responseBuilder.location(location).build();
    }
}
@Path("/token")
@GET
//@Consumes("application/x-www-form-urlencoded")
@Produces({MediaType.APPLICATION_JSON})
	public Response token() 
			throws OAuthSystemException {
	//	MultivaluedMap<String, String> form = new MultivaluedMap<String, String>();
    OAuthTokenRequest oauthRequest =null;
    OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
 
    log.info("API accessed: token");

    try {
    	//System.out.println(formParams.toString());
    
    	//
        oauthRequest = new OAuthTokenRequest(new OAuthRequestWrapper(inRequest)); 
       
      //do checking for different grant types
        if (!oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE)
            .equals(GrantType.AUTHORIZATION_CODE.toString()) && !oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE)
            .equals(GrantType.REFRESH_TOKEN.toString())) {
            
        	throw OAuthProblemException.error("unsupported_grant_type").description("Grant types authorization_code and refresh_token supported");
            
        }
        
        //If client is using authorization_code to get new access token
        if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE)
                .equals(GrantType.AUTHORIZATION_CODE.toString())) {
        	
        	String code = oauthRequest.getParam(OAuth.OAUTH_CODE);
        	String redirect_uri = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);
        	String client_id = oauthRequest.getParam(OAuth.OAUTH_CLIENT_ID);
        	HashMap<String,String> m = new HashMap<String,String>();
 		    m.put("clientid", client_id);
        	
        	vhomeAPI api = new vhomeAPI();
 		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end");
 		    
 		    List<vhomeClient> c = api.getClient(m);
 		    api.close();
 		    if(c.size()==0) throw OAuthProblemException.error("invalid_client").description("Client not registered");
 		    if(!c.get(0).getRedirecturi().equals(redirect_uri)) throw OAuthProblemException.error("invalid_grant").description("redirect_uri registered value mismatch");
 		    
 		    api = new vhomeAPI();
 		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end");
 		    m.clear();
 		    m.put("clientid", client_id);
 		    m.put("code", code);
 		    List<vhomeAccess> a = api.getAccess(m);api.close();
 		    System.out.print("a size"+ a.size() );
 		    if(a.size()!=1 ) throw OAuthProblemException.error("invalid_grant").description("Invalid authorization_code");
 		    if(a.get(0).getValid()==0) throw OAuthProblemException.error("invalid_grant").description("Invalid authorization_code");
 		    
 		    Timestamp ts = Timestamp.valueOf(a.get(0).getIssuedatCode());
 		    //System.out.println(1000* a.get(0).getExpiresCode() + "....." +System.nanoTime()/1000000 + "......"+ ts.getTime() );
 		    if(1000* a.get(0).getExpiresCode() + ts.getTime() < (System.nanoTime()/1000000) )throw OAuthProblemException.error("invalid_grant").description("authorization_code expired"); 
 		    
 		    //everything is checked, set, issue access token
 		   
 		    
 		    String accessToken = oauthIssuerImpl.accessToken(); 
 		    String refreshToken = oauthIssuerImpl.refreshToken();
 		    
 		    api = new vhomeAPI();
 		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end"); 		  
 		    m.clear();
 		    m.put("accesstoken", accessToken);
 		    m.put("refreshtoken", refreshToken);
 		    m.put("valid", "0");
 		    m.put("expiresToken",Config.TokenLifespan+"");
 		    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 		    m.put("issuedatToken", dateFormatLocal.format(new Date()));
 		    
 		    HashMap<String,String> n = new HashMap<String,String>();
 		    n.put("clientid", client_id);
 		    n.put("code", code);
 		    api.updateAccess(m, n);
 		    
 		    OAuthResponse response = OAuthASResponse
 		            .tokenResponse(HttpServletResponse.SC_OK)
 		            .setAccessToken(accessToken).setRefreshToken(refreshToken)
 		            .setExpiresIn(Config.TokenLifespan+"")
 		            .buildJSONMessage();
 		   
 		    
 		   log.info("Response: "+response.getResponseStatus()+", return: access_token: "+accessToken+", refresh_token: "+refreshToken);
 		        return Response.status(response.getResponseStatus()).entity(response.getBody()).build();

                        
            
            
            }
    
        //do checking for different grant types
        /*
         else if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE)
            .equals(GrantType.PASSWORD.toString())) {
            if (!oauthRequest.getPassword().equals("pass")
                || !oauthRequest.getUsername().equals("username")) {
                OAuthResponse response = OAuthASResponse
                    .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                    .setError(OAuthError.TokenResponse.INVALID_GRANT)
                    .setErrorDescription("invalid username or password")
                    .buildJSONMessage();
                return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
            }
        } */ 
        
        
        // If client is using refresh token to get new access token
         /*i.e. else if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE)
            .equals(GrantType.REFRESH_TOKEN.toString()))*/
        else 
         {
         	String refresh_token = oauthRequest.getParam(OAuth.OAUTH_REFRESH_TOKEN);
         	
         	String client_id = oauthRequest.getParam(OAuth.OAUTH_CLIENT_ID);
         	HashMap<String,String> m = new HashMap<String,String>();
  		    m.put("clientid", client_id);
         	
         	vhomeAPI api = new vhomeAPI();
  		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end");
  		    
  		    List<vhomeClient> c = api.getClient(m);
  		    api.close();
  		    
 		    if(c.size()==0) throw OAuthProblemException.error("invalid_client").description("Client not registered");
 		    
 		    
 		    api = new vhomeAPI();
 		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end");
 		    m.clear();
 		    m.put("clientid", client_id);
 		    m.put("refreshtoken", refresh_token);
 		    
 		    List<vhomeAccess> a = api.getAccess(m);api.close();
 		    
 		    if(a.size()!=1 ) throw OAuthProblemException.error("invalid_grant").description("Invalid refresh_token");
 		    
 		    Timestamp ts = Timestamp.valueOf(a.get(0).getIssuedatToken());
 		    //System.out.println(1000* a.get(0).getExpiresCode() + "....." +System.nanoTime()/1000000 + "......"+ ts.getTime() );
 		    if(1000* a.get(0).getExpiresToken() + ts.getTime() < (System.nanoTime()/1000000) )throw OAuthProblemException.error("invalid_grant").description("refresh_token expired"); 
        	 
 		    //everything is checked, set, issue access token
 		   
 		    
 		    String newAccessToken = oauthIssuerImpl.accessToken(); 
 		    String newRefreshToken = oauthIssuerImpl.refreshToken();
 		    
 		    api = new vhomeAPI();
 		    if(api.init()!=1) throw OAuthProblemException.error("server_error").description("Database connection error at server end"); 		  
 		    m.clear();
 		    m.put("accesstoken", newAccessToken);
 		    m.put("refreshtoken", newRefreshToken);
 		    m.put("valid", "0");
 		    m.put("expiresToken",Config.TokenLifespan+"" );
 		    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 		    m.put("issuedatToken", dateFormatLocal.format(new Date()));
 		    
 		    HashMap<String,String> n = new HashMap<String,String>();
 		    n.put("clientid", client_id);
 		    n.put("refreshtoken", refresh_token);
 		    api.updateAccess(m, n);
 		    
 		    OAuthResponse response = OAuthASResponse
 		            .tokenResponse(HttpServletResponse.SC_OK)
 		            .setAccessToken(newAccessToken).setRefreshToken(newRefreshToken)
 		            .setExpiresIn(""+Config.TokenLifespan)
 		            .buildJSONMessage();
 		   log.info("Response: "+response.getResponseStatus()+", return: new_access_token: "+newAccessToken+", new_refresh_token: "+newRefreshToken);
 		    
 		        return Response.status(response.getResponseStatus()).entity(response.getBody()).build();

        	 
        }

        /*
        if (!oauthRequest.getParam(OAuth.OAUTH_CLIENT_ID).equals("clientid")) {
            OAuthResponse response =
                OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                    .setError(OAuthError.TokenResponse.INVALID_CLIENT).setErrorDescription("client_id not found")
                    .buildJSONMessage();
            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
        }
         
        
        OAuthResponse response = OAuthASResponse
            .tokenResponse(HttpServletResponse.SC_OK)
            .setAccessToken(oauthIssuerImpl.accessToken())
            .setExpiresIn("3600")
            .buildJSONMessage();

        return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
        */
        
    } catch (OAuthProblemException e) {
    	e.printStackTrace();
        OAuthResponse res = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
            .buildJSONMessage();
        log.warn(e.getError()+","+e.getDescription()+","+e.getStackTrace());
        log.info("Response: BAD_REQUEST");
        return Response.status(res.getResponseStatus()).entity(res.getBody()).build();
    }
}
	private boolean tokenInvalid(String accessToken)
	{
		log.info("Validity Access_Token: "+accessToken);
		vhomeAPI api = new vhomeAPI();
		 
		{
		if(api.init()!=1)
			{
			
			return true;
			}
		HashMap<String,String> m = new HashMap<String,String>();
		m.put("accesstoken",accessToken);
		List<vhomeAccess> v = api.getAccess(m);api.close();
		if(v.size()!=1) 
			{
			log.info("Access Token invalid");
			return true;
			}
		
		Timestamp ts = Timestamp.valueOf(v.get(0).getIssuedatToken());
		if(1000* v.get(0).getExpiresToken() + ts.getTime() < (System.nanoTime()/1000000) ) 
			{
			log.info("Access Token valid");
			return true;
		    } 
		else 
			{
			log.info("Access Token expired");
			return false;   
			}
		
		}
		
	}
	private boolean scopeInsufficient(String accessToken, String realm)
	{
		log.info("scope sufficiency: "+accessToken+", realm: "+realm);
		vhomeAPI api = new vhomeAPI();
		 
		
		if(api.init()!=1) {api.close(); return true;}
		HashMap<String,String> m = new HashMap<String,String>();
		m.put("accesstoken",accessToken);
		List<vhomeAccess> v = api.getAccess(m);api.close();
		return !scopeValid(v.get(0).getScope(), realm);

		
		
	}
	private boolean scopeValid(String authorized, String requested)
	{
		
		String[] scope;
		scope = authorized.split("&");
		if(Arrays.asList(scope).contains(requested)) {
			log.info("Scope valid");
			return true;
			}
		else {
			log.info("Scope invalid, requested: "+requested+", registered: "+scope);
			return false;
		}
	}
	private Response resource(HttpServletRequest request, String realm) throws OAuthSystemException {
    	
		
		log.info("Resource Request, realm: "+realm+",request.remoteAddr: "+request.getRemoteAddr()+", trustedHosts: "+Arrays.asList(Config.trustedHosts).toString());
		
    if(Arrays.asList(Config.trustedHosts).contains(request.getRemoteAddr())) 
    	return Response.status(Response.Status.OK).entity("my resource").build();
         
    	
    try {

        // Make the OAuth Request out of this request
        OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request,
            ParameterStyle.QUERY);

        // Get the access token
        String accessToken = oauthRequest.getAccessToken();

        // Validate the access token
        if(tokenInvalid(accessToken)){
        	
        	// Return the OAuth error message
            OAuthResponse oauthResponse = OAuthRSResponse
                .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                .setRealm(realm)
                .setError(OAuthError.ResourceResponse.INVALID_TOKEN)
                .setErrorDescription("access token is expired or invalid")
                .setScope(realm)
                .buildHeaderMessage();

            
            //return Response.status(Response.Status.UNAUTHORIZED).build();
            return Response.status(Response.Status.UNAUTHORIZED)
                .header(OAuth.HeaderType.WWW_AUTHENTICATE,
                    oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE))
                .build();

        	
        
        }
        
        //if(tokenExpired(accessToken)) {.............}        
        if(scopeInsufficient(accessToken,realm)){

            // Return the OAuth error message
            OAuthResponse oauthResponse = OAuthRSResponse
                .errorResponse(HttpServletResponse.SC_FORBIDDEN)
                .setError("insufficient_scope")
                .setRealm(realm)
                .setError(OAuthError.ResourceResponse.INSUFFICIENT_SCOPE)
                .setErrorDescription("requested access scope beyond authorized ")
                .setScope(realm)
                .buildHeaderMessage();

            log.info("Response: FORBIDDEN");
            //return Response.status(Response.Status.UNAUTHORIZED).build();
            return Response.status(Response.Status.FORBIDDEN)
                .header(OAuth.HeaderType.WWW_AUTHENTICATE,
                    oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE))
                .build();

        }

        // Return the resource
        return Response.status(Response.Status.OK).entity("my resource").build();

    } catch (OAuthProblemException e) {
        // Check if the error code has been set
    	
        String errorCode = e.getError();
        
        if (OAuthUtils.isEmpty(errorCode)) {

            // Return the OAuth error message
            OAuthResponse oauthResponse = OAuthRSResponse
                .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                .setRealm(realm)
                .setError("invalid_request")
                .setErrorDescription("missing parameter access_token")
                .buildHeaderMessage();
            
            log.warn("Invalid request: missing parameter: access_token");
            log.info("Response: BAD_REQUEST");
            // If no error code then return a standard 401 Unauthorized response
            return Response.status(Response.Status.BAD_REQUEST)
                .header(OAuth.HeaderType.WWW_AUTHENTICATE,
                    oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE))
                .build(); 
        }

        OAuthResponse oauthResponse = OAuthRSResponse
            .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
            .setRealm(realm)
            .setError(e.getError())
            .setErrorDescription(e.getDescription())
            .setErrorUri(e.getUri())
            .buildHeaderMessage();
        log.warn("Invalid request: "+e.getDescription());
        log.info("Response: BAD_REQUEST");
        
        return Response.status(Response.Status.BAD_REQUEST)
            .header(OAuth.HeaderType.WWW_AUTHENTICATE,
                oauthResponse.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE))
            .build();
    }
}
    @Path("/register")
    @POST
    public Response register(@Context HttpServletRequest request, MultivaluedMap<String, String> form) 
	    		throws OAuthSystemException, NoSuchAlgorithmException {

    		log.info("APIaccess: register");
	        OAuthServerRegistrationRequest oauthRequest = null;
	        try {
	            oauthRequest = new OAuthServerRegistrationRequest(new OAuthRegistrationWrapper(request,form));
	            oauthRequest.discover();
	            oauthRequest.getClientName();
	            oauthRequest.getClientUrl();
	            oauthRequest.getClientDescription();
	            oauthRequest.getRedirectURI();
	            
	            Random r = new Random();

	            String clientid = Long.toString(Math.abs(r.nextLong()), 36);
	            Date t = new Date();
	            String issuedat = new Timestamp(t.getTime()).toString();
	            vhomeAPI api = new vhomeAPI();
	            if(api.init()!=1) throw OAuthProblemException.error("server_error").description("server database unavailable");
	            HashMap<String,String> m = new HashMap<String,String>();
	            m.put("name", oauthRequest.getClientName());
	            m.put("url", oauthRequest.getClientUrl());
	            m.put("description", oauthRequest.getClientDescription());
	            m.put("redirecturi", oauthRequest.getRedirectURI());
	            m.put("clientid", clientid);
	            m.put("issuedat", issuedat);
	            api.addClient(m);api.close();
	            OAuthResponse response = OAuthServerRegistrationResponse
	                .status(HttpServletResponse.SC_OK)
	                .setClientId(clientid)
	            //    .setClientSecret("clientsecret")
	                .setIssuedAt(issuedat)
	              //  .setExpiresIn("86500")
	                .buildJSONMessage();
	            log.info("Response: "+response.getResponseStatus() + " body: "+response.getBody());
	            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();

	        } catch (OAuthProblemException e) {
	        	e.printStackTrace();
	            OAuthResponse response = OAuthServerRegistrationResponse
	                .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
	                .error(e)
	                .buildJSONMessage();
	            
	            log.warn(e.getError()+","+e.getDescription()+","+e.getStackTrace());
	            log.info("Response: BAD_REQUEST");
	            return Response.status(response.getResponseStatus()).entity(response.getBody()).build();
	        }

	    }
	
    /*CONFIGURATION METHODS*/
	@Path("/config")
	@GET
	@RolesAllowed("manager")
	public Response getConfig() {
	
		int strlen = Arrays.asList(Config.trustedHosts).toString().length();
		String dbStatus = "";
		vhomeAPI v = new vhomeAPI();
		int i = v.init();
		if(i==1) {dbStatus ="Database Connection OK" ;}
		else if(i==-1) {dbStatus ="Database Error: Database driver Not Found!"  ;}
		else if(i==-2) {dbStatus ="Database Error: Could not connect to database"  ;}
		else if(i==-3) {dbStatus ="Database Error: SQL Exception"  ;}

		 String html= new String("<html><h2>VHome</h2><style>ul.nav { border-bottom:1px solid gray; }ul.nav li {display:inline;position:relative;padding:5px 5px 5px 5px;top:-5px;border:1px solid gray;background-color:lightgray;margin-left:5px;}ul.nav li.selected {background-color:white;border-bottom:none;top:-4px;}</style><ul class='nav'><li ><a href='"+inRequest.getContextPath()+"/home"+"'>Status</a></li><li class='selected' ><a href='"+inRequest.getContextPath()+"/config'"+">Configuration</a></li><li><a href='http://"+inRequest.getServerName()+":"+inRequest.getLocalPort()+"/manager/html'>App Manager</a></li><li  ><a href='"+inRequest.getContextPath()+"/log'>Log Viewer</a></li></ul>");
		
				html+= // "<title>" + "VHome Configuration" + "</title>"
				 "Database</h3> <h4><form method='post' action='"+inRequest.getContextPath()+"/config' ><br/>"
				+ "Driver : <input name='driver' type='text' size='100' value='"+ Config.driver.toString()+"' />"  
				+ "<br/> JDBC String: <input name='jdbcstring' type='text' size='100' value='" + Config.DBurl+"' />"
				+ "<br/> Username: <input name='username' type='text' size='100' value='" + Config.userName +"' />"
				+ "<br/>Password: <input name='password' type='password' value='" + Config.password+"' />"
				+ "<br/>SQL Dialect: <input name='sqldialect' type='text' size='100' value='" + Config.sqldialect.toString()+"' />"
				+"<br/> ("+Arrays.asList(SQLDialect.values()).toString()+")"
				+"<br/> " + dbStatus
				+ "<br/> </h4><h3>Access</h3><h4>Trusted Hosts: " +
				"<input name='trustedhosts' type='text' size='100' value='"  + Arrays.asList(Config.trustedHosts).toString().substring(1, strlen-1).replaceAll("\\s","")+"' />"
				+ "<br/>Code Lifespan: <input name='codelifespan' type='text' size='100' value='" + Config.CodeLifespan+"' />"
				+ "<br/>Access and Refresh Token Lifespan: <input name='tokenlifespan' type='text' size='100' value='" + Config.TokenLifespan+"' />"
				+ "</h4> <h3> " +
				"<input name='set' type=\"submit\" value=\"Save\"  />  " +
				" </form> " + "<input type='button' value='Back' onclick=\"location.href='"+inRequest.getContextPath()+"'\"  />"+
		
				"</h3></body></html> ";
		
		log.info("APIaccess: getConfig: "+ Config.DBurl +","+Config.driver+","+Config.password + ","+
		Config.TokenLifespan +","+Config.CodeLifespan );
		return Response.status(Response.Status.OK).entity(html).build();
	}
	@Path("/config")
	@POST
	@RolesAllowed("manager")
	public Response setConfig(MultivaluedMap<String, String> form) {
		System.out.println(form.get("set"));
		
		if(!form.get("set").get(0).equals("Save")) return Response.status(Response.Status.FORBIDDEN).build();
		Config.driver = form.get("driver").get(0).toString();
		Config.DBurl = form.get("jdbcstring").get(0).toString();
		Config.userName = form.get("username").get(0).toString();
		Config.password = form.get("password").get(0).toString();
		Config.sqldialect = SQLDialect.valueOf(form.get("sqldialect").get(0).toString());
		String newList = form.get("trustedhosts").get(0).toString();
		System.out.println(newList);
		
		String[] newTrustedHost = newList.split(","); 

	    Config.trustedHosts = newTrustedHost;
		Config.CodeLifespan = Integer.parseInt(form.get("codelifespan").get(0).toString());
		Config.TokenLifespan = Integer.parseInt(form.get("tokenlifespan").get(0).toString());
	    
		int strlen = Arrays.asList(Config.trustedHosts).toString().length();
		java.util.Date time = new java.util.Date();
		  
		String dbStatus = "";
		vhomeAPI v = new vhomeAPI();
		int i = v.init();
		if(i==1) {dbStatus ="Database Connection: OK" ;}
		else if(i==-1) {dbStatus ="Database Connection Error: Database driver Not Found!"  ;}
		else if(i==-2) {dbStatus ="Database Connection Error: Could not connect to database"  ;}
		else if(i==-3) {dbStatus ="Database Connection Error: SQL Exception"  ;}
		
		
		 String html= new String("<html><h2>VHome</h2><style>ul.nav { border-bottom:1px solid gray; }ul.nav li {display:inline;position:relative;padding:5px 5px 5px 5px;top:-5px;border:1px solid gray;background-color:lightgray;margin-left:5px;}ul.nav li.selected {background-color:white;border-bottom:none;top:-4px;}</style><ul class='nav'><li ><a href='"+inRequest.getContextPath()+"/home"+"'>Status</a></li><li class='selected' ><a href='"+inRequest.getContextPath()+"/config'"+">Configuration</a></li><li><a href='http://"+inRequest.getServerName()+":"+inRequest.getLocalPort()+"/manager/html'>App Manager</a></li><li  ><a href='"+inRequest.getContextPath()+"/log'>Log Viewer</a></li></ul>");
		
				html+= // "<title>" + "VHome Configuration" + "</title>"
				 "<body><h2>VHome Configuration</h2><h3>"
				+ "Database</h3> <h4><form method='post' action='"+inRequest.getContextPath()+"/config' ><br/>"
				+ "Driver : <input name='driver' type='text' size='100' value='"+ Config.driver.toString()+"' />"  
				+ "<br/> JDBC String: <input name='jdbcstring' type='text' size='100' value='" + Config.DBurl+"' />"
				+ "<br/> Username: <input name='username' type='text' size='100' value='" + Config.userName +"' />"
				+ "<br/>Password: <input name='password' type='password' value='" + Config.password+"' />"
				+ "<br/>SQL Dialect: <input name='sqldialect' type='text' size='100' value='" + Config.sqldialect.toString()+"' />"
				+ "<br/> "+"<br/> ("+Arrays.asList(SQLDialect.values()).toString()+")"
				+ "<br/> " + dbStatus
				+"<br/></h4><h3>Access</h3><h4>Trusted Hosts: " +
				"<input name='trustedhosts' type='text' size='100' value='" + Arrays.asList(Config.trustedHosts).toString().substring(1, strlen-1).replaceAll("\\s","")+"' />"
				+ "<br/>Code Lifespan: <input name='codelifespan' type='text' size='100' value='" + Config.CodeLifespan+"' />"
				+ "<br/>Access and Refresh Token Lifespan: <input name='tokenlifespan' type='text' size='100' value='" + Config.TokenLifespan+"' />"
				+ "</h4> <h3> " +
				"<input name='set' type=\"submit\" value=\"Save\"  /> </form> "+ "<input type='button' value='Back' onclick=\"location.href='"+inRequest.getContextPath()+"/home'\"  />"+
				" </form> <br/><i>Configuration Saved at </i>" + new Timestamp(time.getTime()) + 
				"</h3></body></html> ";
		log.info("APIaccess: setConfig, Newhtml: "+html);
		return Response.status(Response.Status.OK).entity(html).build();
	}


	/* VHOME HOMEPAGE*/
@GET
@Path("/home")
@RolesAllowed("manager")
@Produces({MediaType.TEXT_HTML})
	public String home() throws OAuthSystemException {
	
	String resp="";
	int status=1; long start=0,end=0;
	 try {
		 
		 log.info("APIaccess: home");
		 start = System.currentTimeMillis();
			URL url = new URL("http://blizzard.cs.uwaterloo.ca");
			URLConnection conn = url.openConnection ();

			// Get the response
			BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuffer sb = new StringBuffer();
			String line;

				while ((line = rd.readLine()) != null	)
				{
				sb.append(line);
				}
			rd.close();
			
		end = System.currentTimeMillis();
		
	 	} 
	 catch (Exception e) 
	   {
		 status=0;
		 e.printStackTrace();
		 log.info("APIaccess: home, Exception: "+e.getStackTrace());
	   } 
		
	 

		 
		 resp="<html><h2>VHome</h2>";
		 resp+= new String("<style>ul.nav { border-bottom:1px solid gray; }ul.nav li {display:inline;position:relative;padding:5px 5px 5px 5px;top:-5px;border:1px solid gray;background-color:lightgray;margin-left:5px;}ul.nav li.selected {background-color:white;border-bottom:none;top:-4px;}</style><ul class='nav'><li class='selected'><a href=''>Status</a></li><li><a href='"+inRequest.getContextPath()+"/config'"+">Configuration</a></li><li><a href='http://"+inRequest.getServerName()+":"+inRequest.getLocalPort()+"/manager/html'>App Manager</a></li><li><a href='"+inRequest.getContextPath()+"/log'>Log Viewer</a></li></ul>");
		resp += "<table border='2'>";
		
		resp+="<tr><td>Status</td>";
		if(status==0)
			resp+= "<td>OFFLINE</td>";
		if(status==1)
		{
		resp+= "<td>ONLINE, ("+(end-start)+"ms)</td>";
		resp+="</tr>";
		}
		resp+="<tr><td>URL</td><td>http://"+inRequest.getServerName()+":"+inRequest.getServerPort()+"/vhome</td></tr>";
		resp+="<tr><td>IP</td><td>"+inRequest.getLocalAddr()+"</td></tr>";
		
		vhomeAPI v = new vhomeAPI();
		int i = v.init();
		String dbStatus="";
		if(i==1) {dbStatus ="OK" ;}
		else if(i==-1) {dbStatus ="Error: Database driver Not Found!";}
		else if(i==-2) {dbStatus ="Error: Could not connect to database";}
		else if(i==-3) {dbStatus ="Error: SQL Exception";}
		
		resp+="<tr><td>Database Status:</td><td>"+dbStatus+"</td></tr>";
		resp+="</table>"; 
		resp+=	"</html>";
		return resp;
				 
	  }

@GET
@Path("/log")
@RolesAllowed("manager")
@Produces({MediaType.TEXT_HTML})
	public Response log() {
	String catalina_home = System.getProperty("catalina.home"); 
	 String resp="", content="";
	try {
	    BufferedReader in = new BufferedReader(new FileReader(catalina_home+"/logs/vhome.log"));
	    String str;
	    while ((str = in.readLine()) != null) {
	       content+=str;
	    }
	    in.close();
	   
	    content = ""+content;
	    resp="";
	    resp="<html><h2>VHome</h2>";
		 resp+= new String("<style>ul.nav { border-bottom:1px solid gray; }ul.nav li {display:inline;position:relative;padding:5px 5px 5px 5px;top:-5px;border:1px solid gray;background-color:lightgray;margin-left:5px;}ul.nav li.selected {background-color:white;border-bottom:none;top:-4px;}</style><ul class='nav'><li ><a href='"+inRequest.getContextPath()+"/home"+"'>Status</a></li><li><a href='"+inRequest.getContextPath()+"/config'"+">Configuration</a></li><li><a href='http://"+inRequest.getServerName()+":"+inRequest.getLocalPort()+"/manager/html'>App Manager</a></li><li class='selected' ><a href='"+inRequest.getContextPath()+"/log'>Log Viewer</a></li></ul>");
		
	    resp +="<h3><a href=\"mailto:vhomehelp@gmail.com?subject=VHomeLog:"+inRequest.getServerName()+"&body=" +URLEncoder.encode(content,"UTF-8")
	    		+"\">Click here to e-mail log</a></h3>"+"<hr/>"+ content+"</html>";
	  
	    
	} 
	
	catch (IOException e) {
	
		content = "exception in reading log: "+e.getStackTrace();
		try {
			resp ="<html><h2>Log</h2><br/><h3><a href=\"mailto:vhomehelp@gmail.com?subject=VHomeLog:"+inRequest.getServerName()+"&body=" +URLEncoder.encode(content,"UTF-8")
					+"\">Click here to e-mail log</a></h3>"+"<hr/>"+ content+"</html>";
		} 
		catch (Exception e1) {
			resp ="<html><h2>Log</h2><br/><h3><a href=\"mailto:vhomehelp@gmail.com?subject=VHomeLog:"+inRequest.getServerName()+"&body=errorEncodingExceptionTrace\">Click here to e-mail log</a></h3>"+"<hr/>"+ content+"</html>";
		}
	    
		
	}
	
	 return Response.status(Status.OK).entity(resp).build();
	
	}


}
	


	/*
	@Path("/accessmanagement")
	@GET
	@RolesAllowed("manager")
	@Produces(MediaType.TEXT_HTML)
	public Response accessmanagement()
	{
		
		
	}*/











